import { DrawerForm } from '@ant-design/pro-form';
import { useEffect, useState } from 'react';
import type { Key } from 'react';
import { Button, Card } from 'antd';
import Fields from './Fields';
import Search from './Search';
import EditTable from './EditTable';

import styles from './style.less';
import { groupBy, isArray, isObject } from 'lodash';
import type { FieldType } from './type';
import { drawerOrModalVisibleChange } from '@/utils/utils';

type Props = {
  visible: boolean;
  moduleTitle: string;
  subtitle?: string;
  rowKey: string;
  originIds: Key[];
  fieldsConfig: FieldType[];
  getExtraUpdateParams?: (result: any, nestedResult: any) => any;
  queryByIds: (ids: number[]) => Promise<any>;
  batchUpdate: (data: any) => Promise<any>;
  onBatchSaved: () => void;
  onClose: () => void;
};

const BatchEdit: React.FC<Props> = ({
  visible,
  moduleTitle,
  subtitle,
  rowKey,
  originIds,
  fieldsConfig,
  queryByIds,
  batchUpdate,
  onBatchSaved,
  onClose,
}) => {
  const initialSelectedFields = fieldsConfig
    .filter((item) => item.defaultSelected)
    .map((item) => item.field);
  const [selectedFields, setSelectedFields] = useState<string[]>(initialSelectedFields);
  const [dataSource, setDataSource] = useState<any[]>([]);
  const [recordList, setRecordList] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [inEditMode, setInEditMode] = useState(false);
  const [selectedIds, setSelectedIds] = useState<Key[]>([]);

  useEffect(() => {
    drawerOrModalVisibleChange(visible);
  }, [visible]);

  useEffect(() => {
    if (originIds.length > 0) {
      setSelectedIds(originIds);
    }
  }, [originIds]);

  const getFieldValue = (key: string, value: any) => {
    const field = fieldsConfig.find((item: FieldType) => item.field === key);
    return field?.format2Frontend ? field?.format2Frontend(value) : value;
  };

  const onSearch = async (ids: number[]) => {
    setLoading(true);
    const res = await queryByIds(ids);
    setLoading(false);
    const temp = res.data.list ? res.data.list : res.data;
    const data = temp.map((item: Record<string, any>) => {
      return Object.keys(item).reduce((result, key) => {
        const ret = { ...result };
        if (isObject(item[key]) && !isArray(item[key])) {
          Object.keys(item[key]).forEach((subKey) => {
            const retKey = `${key}.${subKey}`;
            ret[retKey] = getFieldValue(retKey, item[key][subKey]);
          });
        } else {
          ret[key] = getFieldValue(key, item[key]);
        }
        return ret;
      }, {});
    });
    setDataSource(data);
    setRecordList(data);
  };

  const onVisibleChange = (value: boolean) => {
    if (value) {
      if (selectedIds && selectedIds.length > 0) {
        onSearch(selectedIds as number[]);
      }
    } else {
      onClose();
      setSelectedFields(initialSelectedFields);
      setDataSource([]);
      setRecordList([]);
      setInEditMode(false);
    }
  };

  const onValuesChange = (_: any, allValues: any) => {
    const fields = Object.keys(allValues).reduce((result, key) => {
      return result.concat(allValues[key]);
    }, []);
    setSelectedFields(fields);
  };

  const fieldGroups = groupBy(fieldsConfig, (item) => item.group);
  const initialValues = Object.keys(fieldGroups).reduce((result, key) => {
    const ret = { ...result };
    const data = fieldGroups[key].filter((item) => item.defaultSelected).map((item) => item.field);
    if (data.length > 0) {
      ret[key] = data;
    }
    return ret;
  }, {});

  const onDataChange = (data: any[]) => {
    setRecordList(data);
  };

  const batchSaved = () => {
    setDataSource(recordList);
    onBatchSaved();
  };

  return (
    <DrawerForm
      title={`批量编辑${subtitle ? ` - ${subtitle}` : ''}`}
      width="100%"
      visible={visible}
      className={styles.batchEditDrawer}
      onVisibleChange={onVisibleChange}
      onValuesChange={onValuesChange}
      initialValues={initialValues}
      drawerProps={{
        destroyOnClose: true,
      }}
      submitter={{
        render: () => {
          return [
            <Button
              key="close"
              onClick={() => {
                onVisibleChange(false);
              }}
            >
              关闭
            </Button>,
          ];
        },
      }}
      onClick={() => {
        setInEditMode(false);
      }}
    >
      <Card>
        <Search moduleTitle={moduleTitle} loading={loading} ids={selectedIds} onSearch={onSearch} />
        <Fields fieldsConfig={fieldsConfig} />
      </Card>
      <EditTable
        moduleTitle={moduleTitle}
        rowKey={rowKey}
        loading={loading}
        selectedFields={selectedFields}
        inEditMode={inEditMode}
        dataSource={dataSource}
        recordList={recordList}
        fieldsConfig={fieldsConfig}
        onDataChange={onDataChange}
        changeToEdit={() => {
          setInEditMode(true);
        }}
        batchUpdate={batchUpdate}
        onBatchSaved={batchSaved}
      />
    </DrawerForm>
  );
};

export default BatchEdit;
